package com.corpgovernment.supplier.service;

import com.corpgovernment.api.supplier.soa.constant.ProductTypeEnum;
import com.corpgovernment.common.apollo.OrganizationApollo;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.enums.SiteEnum;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.operatelog.service.pojo.ProductUrlPojo;
import com.corpgovernment.organization.vo.PageVo;
import com.corpgovernment.supplier.entity.db.MbSupplierProduct;
import com.corpgovernment.supplier.mapper.MbSupplierProductMapper;
import com.corpgovernment.supplier.vo.MbSupplierProductVo;
import com.corpgovernment.supplier.vo.OperatorTypeVo;
import com.corpgovernment.supplier.vo.ProductUrlVo;
import com.corpgovernment.supplier.vo.QueryProductUrlListRequest;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.ctrip.corp.obt.shard.context.PageContext;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.pagination.IPage;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MbSupplierProductService {

    @Autowired
    private MbSupplierProductMapper mbSupplierProductMapper;
    @Autowired
    private OrganizationApollo organizationApollo;

    public MbSupplierProduct loadProductConfig(String supplierCode, String productType, String operatorType) {

        MbSupplierProduct selectParam = new MbSupplierProduct();
        selectParam.setSupplierCode(supplierCode);
        selectParam.setOperatorType(operatorType);
        selectParam.setProductType(productType);
        return mbSupplierProductMapper.selectOne(selectParam);
    }

    public List<MbSupplierProduct> loadProductConfig(List<String> supplierCodeList, String productType, String operatorType) {
        Example example = new Example(MbSupplierProduct.class);
        example.createCriteria().andIn("supplierCode", supplierCodeList)
                .andEqualTo("operatorType", operatorType)
                .andEqualTo("productType", productType)
                .andEqualTo("isDeleted", 0);
        return mbSupplierProductMapper.selectByExample(example);
    }

    public List<OperatorTypeVo> queryOperatorTypeList(String supplierCode, String productType) throws Exception {

        List<ProductTypeEnum> pList = new ArrayList<>();
        ProductTypeEnum inputProductType = ProductTypeEnum.loadByName(productType);
        if (StringUtils.isBlank(productType)) {
            pList.addAll(Arrays.asList(ProductTypeEnum.flight, ProductTypeEnum.train, ProductTypeEnum.hotel));
        } else if (inputProductType != null) {
            pList.add(inputProductType);
        }

        MbSupplierProduct selectParam = new MbSupplierProduct();
        selectParam.setSupplierCode(supplierCode);
		selectParam.setIsDeleted(false);
        Map<String, List<String>> existsConfig = Optional.ofNullable(mbSupplierProductMapper.select(selectParam)).orElse(new ArrayList<>())
                .stream().filter(Objects::nonNull)
                .collect(Collectors.groupingBy(MbSupplierProduct::getProductType,
                        Collectors.mapping(MbSupplierProduct::getOperatorType, Collectors.toList())));

        List<OperatorTypeVo> operatorTypeVoList = new ArrayList<>();
        for (ProductTypeEnum pEnum : pList) {
            if (pEnum == ProductTypeEnum.i18n_flight) {
                log.error("不支持的业务类型 {}", pEnum);
                continue;
            }

            List<OperatorTypeVo> otv = getOperatorList(pEnum.getOperatorTypeConfig(), pEnum).stream()
                    .filter(o -> {
                        if (CollectionUtils.isEmpty(existsConfig.get(pEnum.name()))) {
                            return true;
                        }
                        return !existsConfig.get(pEnum.name()).contains(o.getId());
                    })
                    .collect(Collectors.toList());
            operatorTypeVoList.addAll(otv);
        }
        return operatorTypeVoList;
    }

    private <T> List<OperatorTypeVo> getOperatorList(Class<T> cls, ProductTypeEnum productTypeEnum) throws Exception {
        Map allOperator = JsonUtils.parseMap(organizationApollo.getAllProductOperatorType());
        if (allOperator == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PRODUCT_OPERATOR_IS_NULL);
        }
        Object productOperator = allOperator.get(productTypeEnum.getUrlApolloKey());
        if (productOperator == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PRODUCT_OPERATOR_IS_NULL);
        }

        List<OperatorTypeVo> result = JsonUtils.parseArray(JsonUtils.toJsonString(productOperator), OperatorTypeVo.class);
        if (CollectionUtils.isEmpty(result)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PRODUCT_OPERATOR_IS_NULL);
        }

        return result;
    }

    public PageVo pageQuery(QueryProductUrlListRequest req) {

        IPage<MbSupplierProductVo> pageInfo = PageContext.startPage(req.getPageNum(), req.getPageSize(),
                () -> mbSupplierProductMapper.pageQuery(req.getNameOrCode(), req.getProductType(), req.getSupplierCode()));
        List<ProductUrlVo> list= new ArrayList<>();
        pageInfo.getRecords().forEach(item ->{
            ProductUrlVo url = new ProductUrlVo();
            BeanUtils.copyProperties(item, url);
            list.add(url);
        });
        return PageVo.builder().pageNum(pageInfo.getCurrent()).pageSize(pageInfo.getSize()).
                count(pageInfo.getTotal()).totalPage(pageInfo.getPages()).list(list).build();
    }

    public ProductUrlPojo convertPojo() {
        IPage<MbSupplierProductVo> objectIPage = PageContext.startPage(1, 10,
                () -> mbSupplierProductMapper.pageQuery(null, null, null));
        PageInfo<MbSupplierProductVo> pageInfo = new PageInfo();
        pageInfo.setList(objectIPage.getRecords());
        pageInfo.setPageSize((int) objectIPage.getSize());
        pageInfo.setPageNum((int) objectIPage.getCurrent());
        pageInfo.setPages((int) objectIPage.getPages());
        pageInfo.setTotal(objectIPage.getTotal());
        ProductUrlPojo urlPojo = null;
        if (pageInfo != null && CollectionUtils.isNotEmpty(pageInfo.getList())) {
            MbSupplierProductVo mbSupplierProductVo = pageInfo.getList().get(0);
            urlPojo = JsonUtils.convert(mbSupplierProductVo, ProductUrlPojo.class);
            urlPojo.setProductType(SiteEnum.get(mbSupplierProductVo.getProductType()).getDesc());

        }
        return urlPojo;
    }

    public void insert(MbSupplierProduct pro) {

        MbSupplierProduct selectParam = new MbSupplierProduct();
        selectParam.setSupplierCode(pro.getSupplierCode());
        selectParam.setProductType(pro.getProductType());
        selectParam.setIsDeleted(Boolean.FALSE);
        List<String> operatorTypeList = Optional.ofNullable(mbSupplierProductMapper.select(selectParam)).orElse(new ArrayList<>()).stream().map(MbSupplierProduct::getOperatorType).collect(Collectors.toList());

        if (operatorTypeList.contains(pro.getOperatorType())) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PRODUCT_TYPE_OCCUPY);
        }
        mbSupplierProductMapper.insertSelective(pro);
    }

    public void update(MbSupplierProduct pro) {
        MbSupplierProduct p = new MbSupplierProduct();
        p.setProductUrl(pro.getProductUrl());
        p.setUserKey(pro.getUserKey());
        p.setId(pro.getId());
        mbSupplierProductMapper.updateByPrimaryKeySelective(p);
    }

    public void delete(Long id) {
        MbSupplierProduct p = new MbSupplierProduct();
        p.setId(id);
        p.setIsDeleted(true);
        mbSupplierProductMapper.updateByPrimaryKeySelective(p);
    }
}
